package com.sunlands.qdcy.tongzhuo.service.task;

import com.sunlands.qdcy.tongzhuo.constant.YN;
import com.sunlands.qdcy.tongzhuo.constant.dic.DIARY_SENSITIVE;
import com.sunlands.qdcy.tongzhuo.exception.SendExceptionUtil;
import com.sunlands.qdcy.tongzhuo.model.DiaryDO;
import com.sunlands.qdcy.tongzhuo.model.DicDO;
import com.sunlands.qdcy.tongzhuo.service.DiaryService;
import com.sunlands.qdcy.tongzhuo.service.DicServiceImpl;
import com.sunlands.qdcy.tongzhuo.util.QRCodeTools;
import com.sunlands.qdcy.tongzhuo.util.SimpleLockUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import static com.sunlands.qdcy.tongzhuo.config.RedisConfig.CacheKeys.CHECK_DIARY;
import static com.sunlands.qdcy.tongzhuo.constant.dic.DIARY_SENSITIVE.*;


@Service
@Slf4j
@EnableScheduling
public class TaskServiceImpl {

    @Autowired
    private SendExceptionUtil sendExceptionUtil;
    @Autowired
    private SimpleLockUtil simpleLockUtil;

    @Value("${eureka.debug:false}")
    private Boolean debug;

    @Autowired
    private DiaryService diaryService;

    @Autowired
    private DicServiceImpl dicService;

    /**
     * 查询最近二十四个小时的订单进行处理，防止历史异常订单过多，造成处理数据膨胀
     * 超过两个小时的订单，关闭交易
     */
    @Scheduled(cron = "${scheduled.checkDiary}")
    public void checkOrder() {
        if (debug) {
            log.warn("本地环境不启动定时");
            return;
        }

        if (!getCheckDiaryLockKey()) {
            return;
        }

        log.info("定时检查日记数据任务开启");
        try {

            Pageable pageable = new PageRequest(0, 10000, new Sort(Sort.Direction.DESC, "createTime"));
            Page<DiaryDO> page = diaryService.find2DayDiary(pageable);
            log.info("查询出日记共 {} 条，", page.getTotalElements());
            int i = 0;
            List<DiaryDO> content = page.getContent();
            List<DiaryDO> list = new ArrayList<>();
            for (DiaryDO diaryDO : content) {

                if (diaryDO.getCreateType().equals(DiaryDO.CreateTypeEnums.FORWARD.type)) {
                    Long rootId = diaryDO.getRootId();
                    DiaryDO di = diaryService.findById(rootId);
                    String imgUrls2 = di.getImgUrls();
                    if (check(imgUrls2) || checkWords(diaryDO.getContent())) {
                        i++;
                        log.info("转发 检测到违规 diary = {}", diaryDO);
                        list.add(diaryDO);
                    }
                }
                String imgUrls = diaryDO.getImgUrls();
                if (check(imgUrls) || checkWords(diaryDO.getContent())) {
                    i++;
                    log.info("检测到违规 diary = {}", diaryDO);
                    list.add(diaryDO);
                }
            }

            log.info("一共需要删除的日记数量 size = {}", list.size());
            list.forEach(diaryDO -> {
                diaryDO.setSeeByMyself(YN.YES.getCode());
                diaryService.save(diaryDO);
            });
        } catch (Exception e) {
            sendExceptionUtil.sendException("定时检查日记数据任务出错 错误信息 = " + e.getMessage(), e);
            log.error("定时检查日记数据任务出错！");
            log.error("", e);
        } finally {
            releaseReturnGoodsLockKey();
        }

    }


    private boolean checkWords(String content) {

        content = content.replace(" ", "");
        DicDO dicDO = dicService.findByCode(DIARY_SENSITIVE.dicName());
        List<String> diaryKyeWords = Arrays.asList(dicDO.filter(content_keywords.name()).getData().split(","));
        for (String key : diaryKyeWords) {
            if (content.contains(key)) {
                return true;
            }
        }
        return false;
    }

    private boolean check(String imgUrls) {
        DicDO dicDO = dicService.findByCode(DIARY_SENSITIVE.dicName());
        List<String> kyeWords = Arrays.asList(dicDO.filter(qr_code_keywords.name()).getData().split(","));
        List<String> kyeWordsWhiteList = Arrays.asList(dicDO.filter(qr_code_keywords_white_list.name()).getData().split(","));
        if (StringUtils.isNotBlank(imgUrls)) {
            List<String> imgList = Arrays.asList(imgUrls.split(","));
            for (String img : imgList) {
                String path = QRCodeTools.deEncodeByPath(img);
                if (StringUtils.isNotBlank(path)) {

                    //白名单的情况，直接放过
                    for (String whiteKey : kyeWordsWhiteList) {
                        if (path.contains(whiteKey)) {
                            return false;
                        }
                    }

                    for (String key : kyeWords) {
                        if (path.contains(key)) {
                            return true;
                        }
                    }

                }
            }
        }
        return false;
    }

//    public List<String> kyeWords = Arrays.asList("qq", "wechat", "weixin", "dingtalk", "m.tb.cn");
//    public List<String> diaryKyeWords = Arrays.asList("QQ", "weixin", "wx", "脉脉", "微信",
//            "会议", "qq", "腾讯", "钉钉", "扣扣",
//            "vx", "tencent", "wechat","TIMING","timing","Timing","TIming","tiMing");


    private boolean getCheckDiaryLockKey() {
        String lockKey = CHECK_DIARY;

        try {
            return simpleLockUtil.acquireLock(lockKey, this.getClass().getName(), 1000 * 60);
        } catch (Exception e) {
            log.error("", e);
        }
        return false;
    }

    private void releaseReturnGoodsLockKey() {
        String lockKey = CHECK_DIARY;
        try {
            simpleLockUtil.releaseLock(lockKey, this.getClass().getName());
        } catch (Exception e) {
            log.error("releaseSendGoodsLockKey error", e);
        }
    }

}
